/**
 * Definition of Environment.
 *
 * \file envi.hpp
 * \author tomby
 * \date 04-01-2009
 **/

/*  Copyright (C) 2009  Tomas 'tomby' Bily

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef __DBC_ENVI__
#define __DBC_ENVI__

namespace dbc {
  namespace peel {

#define IS_DBC_ENVI(X) IS_DBC_TYPE(X, dbc::peel::Environment)
#define DBC_ENVI(X) DBC_TYPE(X, dbc::peel::Environment)
#define DBC_ENVI_PTR(X) DBC_TYPE_PTR(X, dbc::peel::Environment)

    template<int dim>
    class Environment : public Node
    {
      ENTITY_DEF (Environment<dim>);

    public:
      typedef blitz::TinyVector<int, dim> IndexType;

      typedef AdaptiveArray<aa_equal_distr_constr<int, dim> > ZoneType;
      typedef boost::shared_ptr<ZoneType> ZonePtrType;
      typedef std::vector<ZonePtrType> ZoneSetType;
      
      typedef AdaptiveArray<aa_equal_distr_constr<double, dim> > VAXVariableType;
      typedef boost::shared_ptr<VAXVariableType> VAXVariablePtrType;
      typedef std::vector<VAXVariablePtrType> VAXVariableSetType;
      typedef boost::shared_ptr<VAXVariableSetType> VAXVariableSetPtrType;
      typedef std::vector<VAXVariableSetPtrType> VAXVariableMultiSetType;
      
      typedef std::vector<VAX::Ptr> VAXSetType;
      
    public:
      class Border
      {
      public:
	typedef blitz::TinyVector<int, dim> IndexType;
	typedef dbc::LazyContainer<IndexType, Border> IndicesType;

      protected:
	IndicesType indices;

      public:
	typename IndicesType::iterator begin ()
	{ return indices.begin (); }

	typename IndicesType::iterator end ()
	{ return indices.end (); }

	virtual bool update (typename IndicesType::Cache&, typename IndicesType::Range&);
	virtual void size ();
      };

    protected:
      // vaxy
      // hranice
      // oblasti 
      
      IndexType		size;
      ZoneSetType	zones;
      VAXSetType	vaxes;
      VAXVariableMultiSetType vax_variables;
      
    public:
      virtual void update_state ();

      // Consumer
      virtual void consume (PCEntity::Products& products);
  
      // Producer
      virtual Products produce (PCEntity::ProductionMask mask);

      int create_zone_info ();
      ZonePtrType& get_zone_info (int);

      void register_vax (VAX::Ptr vax);
      void init_vax_variables ();
    };

  };
};

#endif
